<?php

namespace app\model;

use Laf\Log;
use mon\orm\Model;
use mon\util\Instance;
use mon\util\Container;
use mon\orm\exception\DbException;

/**
 * 管理端菜单模型
 *
 * Class Menu
 * @copyright 2021-03-24 mon-console
 * @version 1.0.0
 */
class MenuModel extends Model
{
    use Instance;

    /**
     * 操作表
     *
     * @var string
     */
    protected $table = 'menu';

    /**
     * 新增自动写入字段
     *
     * @var array
     */
    protected $insert = ['create_time', 'update_time'];

    /**
     * 更新自动写入字段
     *
     * @var array
     */
    protected $update = ['update_time'];

    /**
     * 验证器
     *
     * @var string
     */
    protected $validate = \app\validate\Menu::class;

    /**
     * 查询信息
     *
     * @param array $where where条件
     * @param mixed $field 查询字段
     * @return mixed
     */
    public function getInfo(array $where, $field = '*')
    {
        $info = $this->where($where)->field($field)->find();
        if (!$info) {
            $this->error = '菜单不存在';
            return false;
        }

        return $info;
    }

    /**
     * 获取树状菜单列表
     *
     * @return array
     */
    public function getTreeList($field = 'id, pid, title', $title = 'title', $where = ['status' => 1])
    {
        $data = $this->where($where)->field($field)->order('sort', 'desc')->select();
        $tree = Container::instance()->tree;
        $dataArr = $tree->data($data)->getTreeArray(0);
        return $tree->getTreeList($dataArr, $title);
    }

    /**
     * 新增路由规则
     *
     * @param array $option
     * @return boolean
     */
    public function add(array $option)
    {
        $check = $this->validate()->data($option)->scope('add')->check();
        if ($check !== true) {
            $this->error = $this->validate()->getError();
            return false;
        }

        $info = [
            'pid'   => $option['pid'],
            'title' => $option['title'],
            'name'  => $option['name'],
            'icon'  => $option['icon'],
            'sort'  => $option['sort'],
            'status'=> $option['status'],
            'remark'=> isset($option['remark']) ? $option['remark'] : '',
        ];

        $this->startTrans();
        try {
            Log::instance()->oss(__FILE__, __LINE__, 'add admin menu', 'sql');
            $save = $this->save($info);
            if (!$save) {
                $this->rollback();
                $this->error = '新增菜单失败';
                return false;
            }

            // 记录操作日志
            $record = AdminLogModel::instance()->record(['action' => '新增菜单', 'content' => json_encode($info, JSON_UNESCAPED_UNICODE)]);
            if (!$record) {
                $this->rollback();
                $this->error = '记录操作日志失败';
                return false;
            }

            $this->commit();
            return true;
        } catch (DbException $e) {
            $this->rollback();
            $this->error = '新增菜单异常';
            Log::instance()->oss(__FILE__, __LINE__, 'add admin menu exception, msg => ' . $e->getMessage(), 'error');
            return false;
        }
    }

    /**
     * 编辑
     *
     * @param array $option
     * @return boolean
     */
    public function edit(array $option)
    {
        $check = $this->validate()->data($option)->scope('edit')->check();
        if ($check !== true) {
            $this->error = $this->validate()->getError();
            return false;
        }

        $baseInfo = $this->getInfo(['id' => $option['idx']]);
        if (!$baseInfo) {
            return false;
        }

        $info = [
            'pid'   => $option['pid'],
            'title' => $option['title'],
            'name'  => $option['name'],
            'icon'  => $option['icon'],
            'sort'  => $option['sort'],
            'status'=> $option['status'],
            'remark'=> isset($option['remark']) ? $option['remark'] : '',
        ];

        $this->startTrans();
        try {
            Log::instance()->oss(__FILE__, __LINE__, 'edit admin menu info', 'sql');
            $save = $this->save($info, ['id' => $option['idx']]);
            if (!$save) {
                $this->rollback();
                $this->error = '修改菜单信息失败';
                return false;
            }

            // 记录操作日志
            $record = AdminLogModel::instance()->record(['action' => '编辑菜单', 'content' => json_encode($info, JSON_UNESCAPED_UNICODE)]);
            if (!$record) {
                $this->rollback();
                $this->error = '记录操作日志失败';
                return false;
            }

            $this->commit();
            return true;
        } catch (DbException $e) {
            $this->rollback();
            $this->error = '编辑菜单异常';
            Log::instance()->oss(__FILE__, __LINE__, 'edit admin menu exception, msg => ' . $e->getMessage(), 'error');
            return false;
        }
    }

    /**
     * 自动完成create_time字段
     * 
     * @param mixed $val 默认值
     * @param array  $row 列值
     * @return string
     */
    protected function setCreateTimeAttr($val)
    {
        return time();
    }

    /**
     * 自动完成update_time字段
     * 
     * @param mixed $val 默认值
     * @param array  $row 列值
     * @return string
     */
    protected function setUpdateTimeAttr($val)
    {
        return time();
    }
}
